/******************************************************************************
** 公司名称：天津柯迪斯科技有限公司
** 版权信息：
** 文件名称： bsp_LCD.c
** 模块名称： 数码管驱动模块
** 版 本 号： V1.0
** 作    者： ZRT
** 备    注：  
** 修改记录： 版本     修改人      时间         修改内容
**           
******************************************************************************/
 
/******************************************************************************
* 头文件
******************************************************************************/
#include "bsp_LCD.h"
#include "Config.h"
#include <stdio.h>


/******************************************************************************
* 全局变量定义 
******************************************************************************/
 
 
/**********************************0       1      2      3      4      5      6      7      8      9    空格*****************/
/**********************************A       B      C      D      E      F      G      H      I      J     K*******************/
/**********************************L       M      N      O      P      Q      R      S      T      U     V*******************/
/**********************************W       X      Y      Z      -                                         *******************/
const uint16_t gusSegTab_13[] = {0xFFf0,0x3E00,0xFBE8,0xFFA8,0xBE38,0xEFB8,0xEFF8,0xFE00,0xFFF8,0xFFB8,0x0000,
                                0xFEF8,0x8FF8,0xE3F0,0x3FE8,0xEBF8,0xE8F8,0xE7F0,0xBEF8,0x00E0,0x3F80,0xBBF8,	
                                0x83F0,0xEEE8,0x0EE8,0x0FE8,0xF8F8,0xFE38,0x08E8,0xEFB8,0x8BF8,0xBFF0,0xB838,	
                                0xBBB8,0xBEF0,0xBFB8,0xEBA8,0x0828};
/*********************************0     1    2    3    4    5    6    7    8    9   空格*****************/
/*********************************A     B    C    D    E    F    G    H    I    J   K*******************/
/*********************************L     M    N    O    P    Q    R    S    T    U   V*******************/
/*********************************W     X    Y    Z    -                             *******************/
const uint8_t  gucSegTab_7[]  = {
                                 0xFC,0x60,0xDA,0xF2,0x66,0xB6,0xBE,0xE0,0xFE,0xF6,0x00, 
                                 0xEE,0x3E,0x9C,0x7A,0x9E,0x8E,0x7C,0x6E,0x08,0x70,0x5E,
                                 0x1C,0xAA,0x2A,0x3A,0xCE,0xE6,0x0A,0xB6,0x1E,0x7C,0x46,
                                 0x56,0x6C,0x76,0x92,0x02
};






                                 /*此表为KD18C屏对应的表，717屏和这个屏差一个位置（A-L循环右移），在显示程序里做了修改*/
const uint16_t code_Tab_b[] =
{
    0xFFf0,  //0
    0x3E00,  //1
    0xFBE8,  //2
    0xFFA8,  //3
    0xBE38,  //4
    0xEFB8,  //5
    0xEFF8,  //6
    0xFE00,  //7
    0xFFF8,  //8
    0xFFB8,  //9
    0xFEF8,  //A
    0x8FF8,  //b
    0xE3F0,  //C
    0x3FE8,  //d
    0xEBF8,  //E
    0xE8F8,  //F
    0x0000,  //" "16
    0xF8F8,  //"P"17
    0x83F0,  //"L"18
    0x0008,  //"-"19
    0xEFB8,  //"S"20
    0xBFF0,  //"V"21
    0xFFf0,  //"O"22
    0xFEf0,  //"N"23
    0xBFB8,  //"Y"24
    0xE3F0,  //"C"25
    0x0E00,  //"i"26
    0x0EE8,  //"n"27
    0x0BE8,  //"c"28
    0x8EF8,  //"h"29
    0x0100,  //"_"30
    0x08E8,  //"r"31
    0xBFF0,  //"u"32,大U//    0x0F, 0xE0,  //"u"32,小u
    0xBEF8,  //"H"33
    0x3FE8,  //"d"34
    0x0FE8,  //"o"35 //=为和上表code_tab对应，717修改，之前小写o为22
    0x8BF8,  //"t"36
    0xEFF0,  //"G"37
};

/*****************************************************************************
* 函数实现 - global ('extern') and local ('static')
******************************************************************************/
static void vBsp_LCD_GPIO_Init(void);

                
/******************************************************************************
** 功  能：LCD初始化
** 参  数：无
** 返回值：无
** 备  注：
******************************************************************************/
void vBsp_LCD_Init(void)
{
    vBsp_LCD_GPIO_Init();     
}
  
/******************************************************************************
** 功  能：LCD GPIO 初始化
** 参  数：无
** 返回值：无
** 备  注： 
******************************************************************************/
static void vBsp_LCD_GPIO_Init(void)
{
    GPIO_InitTypeDef GPIO_InitStruct = {0}; 
    __HAL_RCC_GPIOA_CLK_ENABLE();   
    __HAL_RCC_GPIOB_CLK_ENABLE();
    __HAL_RCC_GPIOC_CLK_ENABLE();
    
    /*LCD  */
    SEG_A1_OFF;
    SEG_A2_OFF;  
    SEG_A_OFF;
    SEG_B_OFF;
    SEG_C_OFF;
    SEG_D_OFF;
    SEG_E_OFF;
    SEG_F_OFF;
    SEG_G_OFF;  
    SEG_DP_OFF;   
    /*Configure GPIO pins : PAPin */
    GPIO_InitStruct.Pin =  SEG_B_Pin|SEG_D_Pin|SEG_G_Pin;
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

    /*Configure GPIO pins : PBPin */
    GPIO_InitStruct.Pin = SEG_C_Pin|SEG_E_Pin|SEG_DP_Pin;
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
    
    /*Configure GPIO pins : PCPin */
    GPIO_InitStruct.Pin = SEG_A_Pin|SEG_F_Pin;
    HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
 
 
    /*Configure GPIO pins : PAPin */
    GPIO_InitStruct.Pin =  SEG_A1_Pin|SEG_A2_Pin;
    GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
 
 
}
 
/******************************************************************************
** 功  能：A1 数码管控制引脚打开
** 参  数：无 
** 返回值：无
** 备  注：因为此处是共阳数码管，供电为5V，单片机为高的时候仍然会有灌电流，导致不能真正关闭，所以关闭的时候需要设置为模拟输入
******************************************************************************/
void vBsp_SEG_A1(uint8_t ucState)
{
    GPIO_InitTypeDef GPIO_InitStruct = {0}; 
    __HAL_RCC_GPIOA_CLK_ENABLE();   
    
    if(0 == ucState)
    {
        SEG_A1_OFF;
        /*Configure GPIO pins : PAPin */
        GPIO_InitStruct.Pin =  SEG_A1_Pin;
        GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
        GPIO_InitStruct.Pull = GPIO_NOPULL;    
        GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
        HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
    }
    else
    {
        SEG_A1_ON;
        /*Configure GPIO pins : PAPin */
        GPIO_InitStruct.Pin =  SEG_A1_Pin;
        GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
        GPIO_InitStruct.Pull = GPIO_NOPULL;    
        GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
        HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
    }
}
/******************************************************************************
** 功  能：A1 数码管控制引脚打开
** 参  数：无 
** 返回值：无
** 备  注：因为此处是共阳数码管，供电为5V，单片机为高的时候仍然会有灌电流，导致不能真正关闭，所以关闭的时候需要设置为模拟输入
******************************************************************************/
void vBsp_SEG_A2(uint8_t ucState)
{
    GPIO_InitTypeDef GPIO_InitStruct = {0}; 
    __HAL_RCC_GPIOA_CLK_ENABLE();   
    
    if(0 == ucState)
    {
        SEG_A2_OFF;
        /*Configure GPIO pins : PAPin */
        GPIO_InitStruct.Pin =  SEG_A2_Pin;
        GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
        GPIO_InitStruct.Pull = GPIO_NOPULL;    
        GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
        HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
    }
    else
    {
        SEG_A2_ON;
        /*Configure GPIO pins : PAPin */
        GPIO_InitStruct.Pin =  SEG_A2_Pin;
        GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
        GPIO_InitStruct.Pull = GPIO_NOPULL;    
        GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
        HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
    }
}
 
/*****************************************以下为LCD应用层函数*******************************************/

/******************************************************************************
** 功  能：写数码管显示 8段 或者 13段
** 参  数：Data-要写入的数据，N_order-写入的数码管索引，Length-要写入的位数
** 返回值：无
** 备  注：
******************************************************************************/
static void vBsp_LCD_WriteSegment(uint32_t Data,enSEG_Nx_TYPE N_order,uint8_t Length)
{
    uint8_t n;
    uint8_t ucSegDisFlg = 0;  
 
    for(n = 0;n < Length;n++)
    {
        if(Data & (Length > 8 ? 0x8000 : 0x80))
        {
           ucSegDisFlg = 1;
        }
        else
        {
           ucSegDisFlg = 0;
        }
        Data <<= 1;
 
        switch(N_order)
        {  
            case SEG_N1:
            {
                switch(n)
                {
                  case 0:
                  {
                      if(ucSegDisFlg)
                      {
                        SEG_A_ON ;                         
                      }
                      else
                      {
                        SEG_A_OFF ;                       
                      }               
                      break;
                  }                      
                  case 1:
                  {
                      if(ucSegDisFlg)
                      {
                        SEG_B_ON ;                         
                      }
                      else
                      {
                        SEG_B_OFF ;                       
                      }                            
                      break;
                  }    
                  case 2:
                  {
                      if(ucSegDisFlg)
                      {
                        SEG_C_ON ;                         
                      }
                      else
                      {
                        SEG_C_OFF ;                       
                      }                                
                      break;
                  }                      
                  case 3:
                  {
                      if(ucSegDisFlg)
                      {
                        SEG_D_ON ;                         
                      }
                      else
                      {
                        SEG_D_OFF ;                       
                      }                                
                      break;
                  }    
                  case 4:
                  {
                      if(ucSegDisFlg)
                      {
                        SEG_E_ON ;                         
                      }
                      else
                      {
                        SEG_E_OFF ;                       
                      }                                
                      break;
                  }                      
                  case 5:
                  {
                      if(ucSegDisFlg)
                      {
                        SEG_F_ON ;                         
                      }
                      else
                      {
                        SEG_F_OFF ;                       
                      }                                
                      break;
                  }   
                  case 6:
                  {
                      if(ucSegDisFlg)
                      {
                        SEG_G_ON ;                         
                      }
                      else
                      {
                        SEG_G_OFF ;                       
                      }                                
                      break;
                  }                      
                  case 7:
                  {
                      if(ucSegDisFlg)
                      {
                      }
                      else
                      {
                      }                              
                      break;
                  } 
                  default:
                      break;                      
                }
                vBsp_SEG_A1(1);
                vBsp_SEG_A2(0);            
                break;
            }
            case SEG_N2:
            {
 
                switch(n)
                {
                  case 0:
                  {
                      if(ucSegDisFlg)
                      {
                        SEG_A_ON ;                         
                      }
                      else
                      {
                        SEG_A_OFF ;                       
                      }               
                      break;
                  }                      
                  case 1:
                  {
                      if(ucSegDisFlg)
                      {
                        SEG_B_ON ;                         
                      }
                      else
                      {
                        SEG_B_OFF ;                       
                      }                            
                      break;
                  }    
                  case 2:
                  {
                      if(ucSegDisFlg)
                      {
                        SEG_C_ON ;                         
                      }
                      else
                      {
                        SEG_C_OFF ;                       
                      }                                
                      break;
                  }                      
                  case 3:
                  {
                      if(ucSegDisFlg)
                      {
                        SEG_D_ON ;                         
                      }
                      else
                      {
                        SEG_D_OFF ;                       
                      }                                
                      break;
                  }    
                  case 4:
                  {
                      if(ucSegDisFlg)
                      {
                        SEG_E_ON ;                         
                      }
                      else
                      {
                        SEG_E_OFF ;                       
                      }                                
                      break;
                  }                      
                  case 5:
                  {
                      if(ucSegDisFlg)
                      {
                        SEG_F_ON ;                         
                      }
                      else
                      {
                        SEG_F_OFF ;                       
                      }                                
                      break;
                  }   
                  case 6:
                  {
                      if(ucSegDisFlg)
                      {
                        SEG_G_ON ;                         
                      }
                      else
                      {
                        SEG_G_OFF ;                       
                      }                                
                      break;
                  }                      
                  case 7:
                  {
                      if(ucSegDisFlg)
                      {
                      }
                      else
                      {
                      }                              
                      break;
                  } 
                  default:
                      break;                      
                }
                vBsp_SEG_A1(0);
                vBsp_SEG_A2(1);       
                break;
            }
            default:
                break;   
        }
    }
}

/******************************************************************************
** 功  能：数码管显示数值
** 参  数：Number-数值， OnOff-是否显示，0-不显示，1-显示  ucRefreshBitFlg 数码管A1/A2交替刷新标志位
** 返回值：无
** 备  注：ucRefreshBitFlg 应为正确频率
******************************************************************************/
void vBsp_LCD_DispNum(uint16_t Number,uint8_t OnOff,uint8_t ucRefreshBitFlg)
{
    uint8_t lucG,lucS;     /*十位、百位上的数字*/
    static uint8_t ucReRefreshBitFlg = 0;
    /*防止超量程显示错误*/
    if(Number > 99)
    {
        Number = 99;
    }

    lucS = Number % 100 / 10;
    lucG = Number % 10;

    if(0 == ucRefreshBitFlg)    /*写十位*/
    {
        if(OnOff)
        {
            vBsp_LCD_WriteSegment(gucSegTab_7[lucS],SEG_N1,7);
        }
        else
        {
            vBsp_LCD_WriteSegment(0x00,SEG_N1,7);
        }
    }
    else    /*写个位*/
    {
        if(OnOff)
        {
            vBsp_LCD_WriteSegment(gucSegTab_7[lucG],SEG_N2,7);
        }
        else
        {
            vBsp_LCD_WriteSegment(0x00,SEG_N2,7);
        }  
    }
 
}
 
/******************************************************************************
** 功  能：在速度显示区显示字符
** 参  数：pString-要显示的字符串，OnOff-是否显示，0-不显示，1-显示 ucRefreshBitFlg 数码管A1/A2交替刷新标志位
** 返回值：无
** 备  注：字符K、M，V、W、X、Z不支持显示。
******************************************************************************/
void vBsp_LCD_DispStringAtSpeed(char *pString,uint8_t OnOff,uint8_t ucRefreshBitFlg)
{
	uint8_t lucDigitalIndex;  
    static uint8_t lucIndex = 0;
    static uint8_t ucReRefreshBitFlg = 0;
    enSEG_Nx_TYPE N_x;
 
    if(*(pString) != '\0' && lucIndex < 2)
	{
		/*字符的0-9*/
		if((*(pString) >= '0') && (*(pString) <= '9'))
		{
			lucDigitalIndex = *(pString) - '0';
		}
		/*小写字母a-z*/
		else if((*(pString) >= 'a') && (*(pString) <= 'z'))
		{
			lucDigitalIndex = *(pString) - 'a' + 11; /*段码数组下标为11的数是字母A的字模*/
		}
		/*大写字母A-Z*/
		else if(*pString >= 'A' && *pString <= 'Z')
		{
			lucDigitalIndex = *pString - 'A' + 11;
		}
		/*减号*/
		else if(*pString == '-')
        {
            lucDigitalIndex = 37;   /*37是减号“-”的索引值*/
        }
        /*其它字符以及空格，都显示空格*/
        else
		{
			lucDigitalIndex = 10; /*段码数组下标为10的是空格*/
		}
        switch(lucIndex)
        {
            case 0:
            {
                N_x = SEG_N1;
                SEG_A1_ON;
                SEG_A2_OFF;                
                break;
            }
            case 1:
            {
                N_x = SEG_N1;
                SEG_A2_ON;
                SEG_A1_OFF;                
                break;
            }        
        }
        if(OnOff)
        {
            vBsp_LCD_WriteSegment(gucSegTab_7[lucDigitalIndex],N_x,7);
        }
        else
        {
            vBsp_LCD_WriteSegment(0x00,N_x,7);
        }
	}
    if(ucReRefreshBitFlg != ucRefreshBitFlg)/*按照刷新率*/
    {
        ucReRefreshBitFlg = ucRefreshBitFlg;
        lucIndex++;
        pString++;  
    }   
}
